package com.cxx.purchasecharge.core.config;

import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.cxx.purchasecharge.core.util.StringUtil;

/**
 * A utility class which is used to hold the utility methods for the filesystem.impl package
 */
public class FileSystemUtil
{
    private static final Logger logger = Logger.getLogger(FileSystemUtil.class);

    private static final String MAPPING_WILD_CARD = "*";

    /**
     * Updates the group name collection. If any group name has a wild card *,
     * then any file in CAREFX_PROPS_DIR starts with the substring
     * representative of this group name (from index 0 to index of wild card *)
     * and ends with the ext will be treated as a group name; and this file name
     * without extension shall be added in the group name collection. It will
     * log a warning message if the CAREFX_PROPS_DIR set incorrect.
     * 
     * @param groupNames
     *            The group name with\without a wild card *.
     * @param ext
     *            The file extension which is either .xml or .properties
     * @return an updated group name collection.
     * @throws IllegalArgumentException
     *             if groupNames is null or the ext is null or blank.
     */
    public static Collection<String> updateGroupNameWithWildCard(Collection<String> groupNames, String ext)
    {
        if(groupNames == null)
        {
            throw new IllegalArgumentException(
                    "groupNames can't be null.");
        }
        if (StringUtil.isNullOrBlank(ext))
        {
            throw new IllegalArgumentException(
                    "ext can't be null or empty string");
        }
        
        Collection<String> ret = new HashSet<String>();
        for(String name : groupNames)
        {
            if(name.endsWith (MAPPING_WILD_CARD))
            {
                File f = null;
                try
                {
                    f = new File (BaseConfigUtil.getCxxPropertiesDir ());
                }
                catch(NullPointerException ne)
                {
                    logger.warn ("The CAREFX_PROPS_DIR path is incorrect="+BaseConfigUtil.getCxxPropertiesDir ());
                    return ret;
                }
                
                File[] list = f.listFiles ();
                
                for(File file : list)
                {
                    if(file.isFile ())
                    {
                        String nm = file.getName ();
                        if(nm.startsWith (name.substring (0, name.indexOf (MAPPING_WILD_CARD))) && nm.endsWith (ext))
                        {
                            //remove file extension
                            nm = nm.substring (0, nm.lastIndexOf (ext));
                            
                            if(!ret.contains (nm))
                            {
                                ret.add (nm);
                            }
                        }
                    }
                }              
            }
            else
            {
                if(!ret.contains (name))
                {
                    ret.add (name); 
                }
            }
        }
        return ret;
    }
    
    
    /**
     * Updates the group name collection. If any group name has a wild card *,
     * then any file in CAREFX_PROPS_DIR starts with the substring
     * representative of this group name (from index 0 to index of wild card *)
     * and ends with the ext will be treated as a group name; and this file name
     * without extension shall be added in the group name collection. It will
     * log a warning message if the CAREFX_PROPS_DIR set incorrect.
     * 
     * @param filePath
     * @param groupNames
     *            The group name with\without a wild card *.
     * @param ext
     *            The file extension which is either .xml or .properties
     * @return an updated group name collection.
     * @throws IllegalArgumentException
     *             if groupNames is null or the ext is null or blank.
     */
    public static Collection<String> updateGroupNameWithWildCard(String filePath, Collection<String> groupNames, String ext)
    {
        if( StringUtil.isNullOrBlank (filePath))
        {
            throw new IllegalArgumentException(
                    "filePath can't be null.");
        }
        
        if(groupNames == null)
        {
            throw new IllegalArgumentException(
                    "groupNames can't be null.");
        }
        
        if (StringUtil.isNullOrBlank(ext))
        {
            throw new IllegalArgumentException(
                    "ext can't be null or empty string");
        }
        
        Collection<String> ret = new HashSet<String>();
        for(String name : groupNames)
        {
            if(name.endsWith (MAPPING_WILD_CARD))
            {
                File f = null;
                try
                {
                    f = new File (filePath);
                }
                catch(NullPointerException ne)
                {
                    logger.warn ("Unable to find path: "+filePath);
                    return ret;
                }
                
                File[] list = f.listFiles ();
                
                for(File file : list)
                {
                    if(file.isFile ())
                    {
                        String nm = file.getName ();
                        if(nm.startsWith (name.substring (0, name.indexOf (MAPPING_WILD_CARD))) && nm.endsWith (ext))
                        {
                            //remove file extension
                            nm = nm.substring (0, nm.lastIndexOf (ext));
                            
                            if(!ret.contains (nm))
                            {
                                ret.add (nm);
                            }
                        }
                    }
                }              
            }
            else
            {
                if(!ret.contains (name))
                {
                    ret.add (name); 
                }
            }
        }
        return ret;
    }
    
    public static String readFileToString(String fileNameWithExtension) throws IOException 
    {
        String fileStr = "";
        String cxxPropertiesDir = BaseConfigUtil.getCxxPropertiesDir ();

        if (StringUtils.isNotBlank(cxxPropertiesDir))
        {
            cxxPropertiesDir = cxxPropertiesDir.trim ();
            if (!cxxPropertiesDir.endsWith (File.separator))
            {
                cxxPropertiesDir += File.separator;
            }
            String file = cxxPropertiesDir + fileNameWithExtension;
            logger.info (fileNameWithExtension + " file path is " + file);
            
            fileStr = FileUtils.readFileToString(new File(file), "utf-8");
        }
        return fileStr;
    }
}
